package top.linruchang.bean;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import top.linruchang.enums.RegexFileTypeEnum;
import top.linruchang.util.RegexUtil;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;


/**
 * 作用：
 * 替换后存储的文件newFile、
 * 内容正则规则regexStrAndRegexStrs、
 * 源字符串来自于什么文件类型fileTypes、
 * 需要排除的某种文件customExcludeFileRegexs
 *
 * @author LinRuChang
 * @version 1.0
 * @date 2020/11/03
 * @since 1.8
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class FileAndRules {

    /**
     * 正则处理后内容所存储的文件
     */
    File targetFile;

    /**
     * 文件内容 = 替换字符串与正则规则
     */
    List<ReplaceStrAndRegexStr> regexStrAndRegexStrs = new ArrayList<>();

    /**
     * 文件类型 - 可参考{@link RegexFileTypeEnum}
     * 可以是纯类型字符串
     */
    List<String> fileTypes = new ArrayList<>();

    /**
     * 选择某种文件名正则 - 仅仅是对fileTypes文件的补充，可能想要某个不在fileTypes里面的类型文件
     */
    List<String> customIncludeFileRegexs = new ArrayList<>();

    /**
     * 排除某种文件名正则 - 源文件排除来自这行的文件名正则
     */
    List<String> customExcludeFileRegexs = new ArrayList<>();

    //=========================变量成员方法=====================================

    public FileAndRules setFileTypes(List<String> fileTypes) {
        this.fileTypes = fileTypes;
        formatFileTypesToRegex();
        return this;
    }

    public FileAndRules setTargetFile(String targetFile) {
        this.targetFile = new File(targetFile);
        return this;
    }
    public FileAndRules setTargetFile(File targetFile) {
        this.targetFile = targetFile;
        return this;
    }

    /**
     * 格式化fileTypes元素 - 将其变成匹配类型的正则表达式
     */
    private  void formatFileTypesToRegex() {
        final String regexPrefix = ".+(";
        final String regexSuffix = ")$";
        for (int i = 0; i < fileTypes.size(); i++) {
            String fileType = fileTypes.get(i);
            if (fileType.lastIndexOf("$") != fileType.length() - 1) {
                fileTypes.set(i, regexPrefix + fileType + regexSuffix);
            }
        }
    }

    //=========================功能性成员方法=====================================


    /**
     * <p>
     * description: 判断该文件是否适合作为源文件
     * </p>
     *
     * @param sourceFile 源文件
     * @return boolean
     */
    public boolean sourceIsNedd(File sourceFile) {
        String sourceFilePath = sourceFile.getAbsolutePath();
        boolean isExclude = RegexUtil.isMatchAnyRegex(sourceFilePath, customExcludeFileRegexs);
        boolean isInclude = RegexUtil.isMatchAnyRegex(sourceFilePath, Stream.concat(customIncludeFileRegexs.stream(), fileTypes.stream()).collect(Collectors.toSet()));
        if (isExclude || !isInclude) {
            return false;
        } else {
            return true;
        }
    }

    public String processContent(String sourceContent) {
        for(ReplaceStrAndRegexStr rsars : regexStrAndRegexStrs) {
            sourceContent = rsars.processContent(sourceContent);
        }
        return sourceContent;
    }

    public void addReplaceStrAndRegexStr(ReplaceStrAndRegexStr replaceStrAndRegexStr) {
        regexStrAndRegexStrs.add(replaceStrAndRegexStr);
    }


    //=========================静态方法 - 工厂=====================================


}
